package com.easyadmin.pro.tool;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * packageName com.easyadmin.pro.tool
 *
 * @author 骑着蚂蚁去上天
 * @version JDK 17
 * @className BeanUtils
 * @date 2024/4/7
 * @description 对象转换工具
 */
public class BeanUtils {

    /**
     * 处理集合对象类型
     * @param source
     * @param tClass
     * @param <E>
     * @param <T>
     * @return 集合
     */
    public static <E, T> List<T> conventBeans(List<E> source, Class<T> tClass) {
        List<T> results = new ArrayList<>();
        if (!source.isEmpty()) {
            source.stream().forEach(e -> {
                T data = org.springframework.beans.BeanUtils.instantiateClass(tClass);
                org.springframework.beans.BeanUtils.copyProperties(e, data);
                results.add(data);
            });
        }
        return results;
    }

    /**
     * 处理集合对象类型-可忽略字段
     * @param source
     * @param tClass
     * @param <E>
     * @param <T>
     * @param columnName
     * @return 集合
     */
    public static <E, T> List<T> conventBeans(List<E> source, Class<T> tClass, String... columnName) {
        List<T> results = new ArrayList<>();
        if (!source.isEmpty()) {
            source.stream().forEach(e -> {
                T data = org.springframework.beans.BeanUtils.instantiateClass(tClass);
                org.springframework.beans.BeanUtils.copyProperties(e, data, columnName);
                results.add(data);
            });
        }
        return results;
    }

    /**
     * list转换嵌套Map-Map<Object, Map<Object, List<>>>
     * @param c
     * @param keyExtractor1
     * @param keyExtractor2
     * @param <K1>
     * @param <K2>
     * @param <T>
     * @return
     */
    public static <K1, K2, T> Map<K1, Map<K2, List<T>>> toUniqueValueMapInMapList(Collection<T> c,
                                                                                  Function<T, K1> keyExtractor1,
                                                                                  Function<T, K2> keyExtractor2) {
        return c.stream().collect(Collectors.groupingBy(keyExtractor1::apply,
                Collectors.groupingBy(keyExtractor2::apply,
                        Collectors.collectingAndThen(Collectors.toList(), l -> l))));
    }

    /**
     * list转换嵌套Map-Map<Object, Map<Object, Object>>
     * @param c
     * @param keyExtractor1
     * @param keyExtractor2
     * @param <K1>
     * @param <K2>
     * @param <T>
     * @return
     */
    public static <K1, K2, T> Map<K1, Map<K2, T>> toUniqueValueMapInMap(Collection<T> c,
                                                                        Function<T, K1> keyExtractor1,
                                                                        Function<T, K2> keyExtractor2) {
        return c.stream().collect(Collectors.groupingBy(keyExtractor1::apply,
                Collectors.groupingBy(keyExtractor2::apply,
                        Collectors.collectingAndThen(Collectors.toList(), l -> l.get(0)))));
    }
}